/***********************************************************************************
 * 文件名： polsys_lib.h
 * 作者： 刘言
 * 版本： 1
 * 说明：
 *      常用的一些数据处理相关的宏定义和函数。polsys.h中已经默认包含。
 * 修改记录：
 * 	2021/01/23: 初版。 刘言。
***********************************************************************************/
#ifndef _POLSYS_LIB_H_
#define _POLSYS_LIB_H_

#include "typedef.h"


#define PRE_POW(base, exp) ((exp) == 0 ? 1 : (base) * PRE_POW(base, (exp) - 1))


#define __CONNECT(A,B)   A##B
#define _CONNECT(A,B)   __CONNECT(A,B)
#define CONNECT(A,B)    _CONNECT(A,B)

//16 --> 8 x 2
#undef HIBYTE
#define HIBYTE(v1)              ((u8)((v1)>>8))                      //v1 is UINT16
#undef LOBYTE
#define LOBYTE(v1)              ((u8)((v1)&0xFF))
//8 x 2 --> 16
#undef MAKEWORD
#define MAKEWORD(v1,v2)         ((((u16)(v1))<<8)+(u16)(v2))      //v1,v2 is UINT8
#define MAKE_U16(h,l)           ((((u16)(h))<<8)+(u16)(l))      
#define MAKE_U32(hh,h,l,ll)     ((((u32)(hh))<<24)+(((u32)(h))<<16)+(((u32)(l))<<8) +(u32)(ll))
//32 --> 16 x 2
#undef YBYTE1
#define YBYTE1(v1)              ((u16)((v1)>>16))                    //v1 is UINT32
#undef YBYTE0
#define YBYTE0(v1)              ((u16)((v1)&0xFFFF))
//32 --> 8 x 4
#undef TBYTE3
#define TBYTE3(v1)              ((u8)((v1)>>24))                     //v1 is UINT32
#undef TBYTE2
#define TBYTE2(v1)              ((u8)((v1)>>16))
#undef TBYTE1
#define TBYTE1(v1)              ((u8)((v1)>>8)) 
#undef TBYTE0
#define TBYTE0(v1)              ((u8)((v1)&0xFF))

/** 类型长度检查 */
/**
 * Helper macro to verify a size at compile time.  If this fails, it will
 * produce a negative subscript compiler error.
 */
#define VERIFY_SIZE(type, target_size) \
    typedef char __VERIFY_SIZE__##type[(sizeof(type) == (target_size)) ? 1 : -1]
/**
 * If any of these macros fails it means one of the typedefs in this file
 * does not match the proper size for this platform.
 */
VERIFY_SIZE(u32, 4);
VERIFY_SIZE(s32, 4);
VERIFY_SIZE(u16, 2);
VERIFY_SIZE(u8, 1);
VERIFY_SIZE(byte, 1);



u8 GetMaxU8(u8 *dat, int len);
// 获得u16数组中的最大值
u16 GetMaxU16(u16 *dat, int len);
// 平滑处理曲线，数据为u16数组，处理完后直接更新源数据。
void SmoothWaveU16(u16 *dat, int len);
// 获得一个s16的绝对值
u16 GetAbsS16(s16 v);
// 按字节求和，结果是一个u32。
u32 GetSum_U32(const u8 *buff, u32 len);
// 按字节求和，只保留最低8位。
u8 GetSum_U8(const u8 *buff, u8 len);
// 获得一个8位伪随机数
u8 GetRand8bit(void);
// 判断num是否处于start-end区间
bool IsInRangeU16(u16 num, u16 start, u16 end);
// 字节数组合并成一个u32
u32 MakeU32(u8 * Bytes,u8 Lenght);
// 转BCD编码,78 -> 0x78
u8 DecToBcd(u8 dat);
// 解码BCD编码,0x78 -> 78
u8 BcdToDec(u8 dat);
// 9个u8数中值滤波
u8 MedianFilter8b9(u8 *dat);
// 9个u16数中值滤波
u16 MedianFilter16b9(u16 *dat);
// 20个u16数中值滤波
u16 MedianFilter16b20(u16 *dat);
// n个u16数中值滤波
u16 MedianFilter16bn(u16 *dat, int num);
// 整数开方
u16 IntSqrt(u32 num);
// 整数正幂运算
int IntPow(int base, u16 pow);
// 将十六进制字符串转换成一个int整数 "AABB" => 0x0000AABB
int GetDataFromHexStr(const char *str);
// 将十进制字符串转换成一个int 整数 "4214" => 4214
int GetDataFromDecStr(const char *str);

/**
 * 0~15的整数转换成十六进制字符
 * @param b 0~15 的整数
 * @return '0'~'F'字符
*/
char IntToHexChar(u8 b);

/**
 * 数据按字节转换成十六进制字符串
 * @param str_dest 用于保存转换好的十六进制字符串，末尾会加入0，注意要有足够的空间，避免越界。
 * @param src 数据
 * @param bytes_len 数据长度（字节数）
 * @return 转好的字符串，等于str_dest
*/
char * ToHexStr(char * str_dest, const void *src, int bytes_len);

/**
 * 数据按字节转换成十六进制字符串
 * @param str_dest 用于保存转换好的十六进制字符串，末尾会加入0，注意要有足够的空间，避免越界。
 * @param src 数据
 * @param bytes_len 数据长度（字节数）
 * @param end_data src 中遇到这个数据将提前结束转换。
 * @return 转好的字符串，等于str_dest
*/
char * ToHexStrE(char * str_dest, const void *src, int bytes_len, u8 end_data);

#endif
